package push

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"
	"time"

	// "chainserver/core/utils"

	"github.com/astaxie/beego"
	// "github.com/dustin/go-humanize"

	"chainserver/env"
)

type Player struct {
	UID            int64
	Name           string
	HeadImg        string
	Platform       env.PlatformType
	PlatformId     string
	ForbiddenPush  bool
	NightAllowPush bool
	IsSubscribed   bool
	Province       int64
	City           int64
}

var httpClient *http.Client

func init() {
	httpClient = &http.Client{}
}

func DispatchBroadcastServer(uid int64) (serverIdx int) {
	return int(uid % int64(len(env.BroadcastServers)))
}

func GetBroadcastServerAddress(uid int64, ver string) string {

	return ""
	// if utils.CompareVersion(ver, "1.4.5") <= 0 {
	// 	return ""
	// }

	// if len(env.BroadcastServers) <= 0 {
	// 	return ""
	// }

	// broadcastServer := DispatchBroadcastServer(uid)
	// partAdd := env.BroadcastServers[broadcastServer]
	// if len(partAdd) <= 0 {
	// 	return ""
	// }

	// bcServerAddress := fmt.Sprintf("ws://%s/ws", partAdd)
	// if "prod" == env.RunMode || "audit" == env.RunMode {
	// 	bcServerAddress = fmt.Sprintf("wss://%s/ws", partAdd)
	// }
	// return bcServerAddress
}

func PushToPlayer(from *Player, to *Player, action int, values []int64, goodsId string) {
	//首先向推送服务器发送推送
	var fromUID int64
	var province, city int64
	var fromName, fromHeadImg string
	if from != nil {
		fromUID = from.UID
		fromName = from.Name
		fromHeadImg = from.HeadImg
		province = from.Province
		city = from.City
	}
	// isPushed := false
	broadcastServer := DispatchBroadcastServer(to.UID)
	u := fmt.Sprintf("http://%s/push", env.BroadcastServers[broadcastServer])
	msg := env.BroadcastMessage{
		FromUID:     fromUID,
		FromName:    fromName,
		FromHeadImg: fromHeadImg,
		Province:    province,
		City:        city,
		ToUID:       to.UID,
		Action:      action,
		Values:      values,
		GoodsId:     goodsId,
	}
	body, _ := json.Marshal(&msg)

	res, err := httpClient.Post(u, "application/json", bytes.NewReader(body))
	if err != nil {
		beego.Error("发送推送到游戏广播服务器失败, err:", err.Error())
		return
	}
	defer res.Body.Close()
	buf := new(bytes.Buffer)
	buf.ReadFrom(res.Body)
	beego.Debug(fmt.Sprintf("发送推送到游戏广播服务器, uid: %d, action: %d, msg: %s, code: %d, result: %s", to.UID, action, body, res.StatusCode, buf.String()))

	// msgTxt := makePushTxt(from, to, action, goodsId, values)
	// if !isPushed && to.Platform == env.PlatformTypeHortor && msgTxt != "" {
	// go PushToHortor(to, msgTxt, "push", "", "", 0)
	// }
}

func PushToAllPlayer(from *Player, action, channelCount int, values []int64, goodsId string) {
	// var fromUID int64
	// var province, city int64
	// var fromName, fromHeadImg string
	// if from != nil {
	// 	fromUID = from.UID
	// 	fromName = from.Name
	// 	fromHeadImg = from.HeadImg
	// 	province = from.Province
	// 	city = from.City
	// }
	// msg := env.BroadcastMessage{
	// 	FromUID:     fromUID,
	// 	FromName:    fromName,
	// 	FromHeadImg: fromHeadImg,
	// 	Province:    province,
	// 	City:        city,
	// 	ToUID:       0,
	// 	Action:      action,
	// 	Values:      values,
	// 	GoodsId:     goodsId,
	// }
	// servers := make([]string, 0)
	// if action == env.ActionWorldChat && from != nil {
	// 	count := len(env.BroadcastServers)
	// 	serverCount := utils.Max(1, count/channelCount)
	// 	broadcastServer := DispatchBroadcastServer(from.UID) / serverCount
	// 	for i := 0; i < serverCount; i++ {
	// 		serverId := broadcastServer*serverCount + i
	// 		if serverId < count {
	// 			servers = append(servers, env.BroadcastServers[serverId])
	// 		}
	// 	}
	// 	if channelCount > count {
	// 		msg.ToUID = int64(channelCount / count)
	// 	}
	// } else {
	// 	servers = env.BroadcastServers
	// }
	// body, _ := json.Marshal(&msg)
	// for _, server := range servers {
	// 	go func(body []byte, server string) {
	// 		url := fmt.Sprintf("http://%s/push", server)
	// 		res, err := httpClient.Post(url, "application/json", bytes.NewReader(body))
	// 		if err != nil {
	// 			beego.Error("发送推送到游戏广播服务器失败, error:", err.Error())
	// 			return
	// 		}
	// 		defer res.Body.Close()
	// 	}(body, server)
	// }
}

func makePushTxt(from *Player, to *Player, action int, param string, values []int64) (txt string) {
	// switch action {
	// case env.ActionAttack:
	// 	switch int(values[0]) {
	// 	case env.ActionExtraDamaged:
	// 		return fmt.Sprintf("%s损坏了你的%s，快去复仇吧", from.Name, env.BuildingNames[int(values[1])])
	// 	case env.ActionExtraDestroyed:
	// 		return fmt.Sprintf("%s摧毁了你的%s，快去复仇吧", from.Name, env.BuildingNames[int(values[1])])
	// 	case env.ActionExtraShielded:
	// 		return fmt.Sprintf("%s攻击了你的%s，但被你的护盾防御住了", from.Name, env.BuildingNames[int(values[1])])
	// 	case env.ActionExtraPetShielded:
	// 		return fmt.Sprintf("%s攻击了你的%s，但被你的宠物防御住了", from.Name, env.BuildingNames[int(values[1])])
	// 	case env.ActionExtraMiniShielded:
	// 		return fmt.Sprintf("%s攻击了你的%s，但被你的迷你盾防御住了", from.Name, env.BuildingNames[int(values[1])])
	// 	}
	// case env.ActionSteal:
	// 	return fmt.Sprintf("%s偷走了%s金币，快去复仇吧", from.Name, humanize.Comma(int64(values[0])))
	// case env.ActionWanted:
	// 	return fmt.Sprintf("%s通缉了你，Ta的好友会对你进行攻击，请注意防备！", from.Name)
	// case env.ActionSendMail:
	// 	return fmt.Sprintf("%s给你发送了一封邮件，请登录游戏查看！", from.Name)
	// case env.ActionPrivateChat:
	// 	if values[0] == 1 {
	// 		return fmt.Sprintf("%s给你发送了一条消息，请登录游戏查看！", from.Name)
	// 	} else if values[0] == 5 {
	// 		return fmt.Sprintf("%s同意了你的交换请求，快回来领取吧！", from.Name)
	// 	}
	// case env.ActionCash:
	// 	switch int(values[0]) {
	// 	case env.ActionCashInvite:
	// 		return fmt.Sprintf("好友%s达到50星了，快来领红包呀", from.Name)
	// 	}
	// case env.ActionBeach:
	// 	if len(values) > 0 && values[0] == to.UID {
	// 		return fmt.Sprintf("%s给你成功助威啦，请登录游戏查看！", from.Name)
	// 	}
	// case env.ActionBeachRandom:
	// 	if param != "" {
	// 		return fmt.Sprintf("一个%s从天而降，落在沙滩上了，赶快去看看吧！", param)
	// 	}
	// case env.ActionOctopus:
	// 	if values[0] == 5 {
	// 		return fmt.Sprintf("%s帮你开启了章鱼宝箱，快去领取奖励吧！", from.Name)
	// 	}
	// case env.ActionEnergyFull:
	// 	if len(values) > 0 && values[0] == 1 {
	// 		return "您的能量已经爆棚，是时候给仇人们点颜色瞧瞧了！"
	// 	} else {
	// 		return "海盗先生，能量已回满，继续去掠夺吧！"
	// 	}
	// case env.ActionTree:
	// 	if len(values) > 0 && values[0] == 1 {
	// 		names := []string{"桃子", "西瓜", "椰汁", "香蕉"}
	// 		name := names[values[1]-1]
	// 		return fmt.Sprintf("【森林聚餐活动】%s帮你挂了%d个%s，请登录游戏查看！", from.Name, values[2], name)
	// 	}
	// case env.ActionFlower:
	// 	if len(values) > 1 && values[0] == 1 && values[1] > 1 {
	// 		title := "一心一意"
	// 		if values[1] == 10 {
	// 			title = "十全十美"
	// 		} else if values[1] == 99 {
	// 			title = "天长地久"
	// 		} else if values[1] == 520 {
	// 			title = "我爱你"
	// 		}
	// 		return fmt.Sprintf("%s送了你《%s》玫瑰*%d，请登录游戏查看！", from.Name, title, values[1])
	// 	}
	// case env.ActionKite:
	// 	if len(values) > 0 && values[0] == 1 {
	// 		return fmt.Sprintf("【放风筝】您的好友%s帮你成功助力，快去谢谢他吧！", from.Name)
	// 	}
	// case env.ActionActivityRecall:
	// 	if len(values) > 0 && values[0] == 1 {
	// 		return fmt.Sprintf("【老船长】你成功邀回了一位老船长，快去和他打个招呼去吧！")
	// 	}
	// }

	return
}

func NotifyPush(to *Player, msgType string, delaySeconds int64) {
	if to != nil && to.Platform == env.PlatformTypeHortor {
		params := url.Values{}
		params.Add("uid", fmt.Sprintf("%d", to.UID))
		params.Add("type", msgType)
		// msgTxt := params.Encode()
		if msgType == "energyFull" {
			pushAt := time.Now()
			pushAt = pushAt.Add(time.Second * time.Duration(delaySeconds))
			if pushAt.Hour() >= 22 {
				delaySeconds += int64((8 + 24 - pushAt.Hour()) * 3600)
			} else if pushAt.Hour() < 8 {
				delaySeconds += int64((8 - pushAt.Hour()) * 3600)
			}
		}
		// go PushToHortor(to, msgTxt, "delayed_callback", msgType, "", delaySeconds)
	}
}

func DelayPush(to *Player, msgType, content, action string, delaySeconds int64) {
	if to == nil {
		return
	}
	if delaySeconds > 0 {
		pushAt := time.Now()
		pushAt = pushAt.Add(time.Second * time.Duration(delaySeconds))
		if to.ForbiddenPush && (pushAt.Hour() >= 8 && pushAt.Hour() < 22) {
			return
		}
		if !to.NightAllowPush && (pushAt.Hour() >= 22 || pushAt.Hour() < 8) {
			return
		}
		if to.PlatformId == "" || to.Platform != env.PlatformTypeHortor {
			return
		}
	}
	// go PushToHortor(to, content, "delayed_push", msgType, action, delaySeconds)
}

func PushToHortor(to *Player, content, pushType, msgType, action string, delaySeconds int64) {
	// if pushType != "delayed_callback" {
	// 	now := time.Now()
	// 	if to.ForbiddenPush && delaySeconds < 60 && (now.Hour() >= 8 && now.Hour() < 22) {
	// 		return
	// 	}
	// 	if !to.NightAllowPush && delaySeconds < 60 && (now.Hour() >= 22 || now.Hour() < 8) {
	// 		return
	// 	}
	// }
	// if to.PlatformId == "" {
	// 	return
	// }
	// conf := env.PlatformConfs[env.PlatformTypeHortor]
	// notifyURL := conf.NotifyUrl
	// gameID := conf.AppId
	// secret := conf.AppKey
	// if len(to.PlatformId) == 32 {
	// 	count := len(conf.WxGameNotifyUrls)
	// 	//randomNum := rand.Intn(100)
	// 	url := conf.WxGameNotifyUrls[int(to.UID)%count]
	// 	notifyURL = url
	// 	gameID = conf.WxGameID
	// 	secret = conf.WxGameSecret
	// }
	// data := url.Values{}
	// data.Add("gameId", gameID)
	// data.Add("userIds", to.PlatformId)
	// data.Add("content", content)
	// data.Add("type", pushType)
	// sign := utils.GenSignForHortorWithKey(data, secret)
	// if pushType == "delayed_callback" || pushType == "delayed_push" {
	// 	data.Add("delay", fmt.Sprintf("%d", delaySeconds))
	// 	data.Add("taskName", msgType)
	// }
	// if action != "" {
	// 	data.Add("action", action)
	// }
	// data.Add("sign", sign)
	// res, err := httpClient.PostForm(notifyURL, data)
	// if err != nil {
	// 	beego.Error("发送推送到平台服务器失败，err: ", err.Error())
	// 	return
	// }
	// defer res.Body.Close()
	// buf := new(bytes.Buffer)
	// buf.ReadFrom(res.Body)
	// // go graylog.Error("发送推送到平台服务器", map[string]interface{}{
	// // 	"playerId":    to.UID,
	// // 	"name":        to.Name,
	// // 	"userId":      to.PlatformId,
	// // 	"content":     content,
	// // 	"pushType":    pushType,
	// // 	"delaySecond": delaySeconds,
	// // 	"resultCode":  res.StatusCode,
	// // 	"resultMsg":   buf.String(),
	// // })
	// if res.StatusCode != 200 {
	// 	beego.Error("发送推送到平台服务器失败, error:", buf.String())
	// 	return
	// }
}
